/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    private Map<Integer, Integer> indexMap;
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        //根据前序遍历与中序遍历重构二叉树
        int n = preorder.length;
        indexMap = new HashMap<Integer, Integer>();
        for(int i = 0; i < n; i++){
            indexMap.put(inorder[i],i);
        }
        return myBuildTree(preorder, inorder, 0, n-1, 0, n-1);
    }
    public TreeNode myBuildTree(int[] preorder, int[] inorder, int pre_left, int pre_right, int in_left, int in_right){
        if(pre_left > pre_right){
            return null;
        }
        //定位前序遍历中的根节点
        int pre_root = pre_left;
        //定位中序遍历中的根节点
        int in_root = indexMap.get(preorder[pre_root]);
        //确定根节点的左子树长度
        int left_subtree_size = in_root - in_left;
        //建立根节点
        TreeNode root = new TreeNode(preorder[pre_root]);
        /*
            [ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]
            [ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]
        */
        // 先序遍历「左边界+1 开始的 left_subtree_size」对应中序遍历「左边界 开始到 根节点定位-1」的元素
        root.left = myBuildTree(preorder, inorder, pre_left + 1, pre_left + left_subtree_size, in_left, in_root - 1);
        // 先序遍历「左边界+1+左子树节点数目 开始到 右边界」对应了中序遍历「从 根节点定位+1 到 右边界」的元素
        root.right = myBuildTree(preorder, inorder, pre_left + left_subtree_size + 1, pre_right, in_root + 1, in_right);

        return root;
    }
}